using ChatBackend.DTOs;
using ChatBackend.Models;
using ChatBackend.Repositories;

namespace ChatBackend.Services
{
    public class ChatService : IChatService
    {
        private readonly IChatRoomRepository _chatRoomRepository;
        private readonly IMessageRepository _messageRepository;
        private readonly IUserRepository _userRepository;

        public ChatService(
            IChatRoomRepository chatRoomRepository,
            IMessageRepository messageRepository,
            IUserRepository userRepository)
        {
            _chatRoomRepository = chatRoomRepository;
            _messageRepository = messageRepository;
            _userRepository = userRepository;
        }

        public async Task<ChatRoomDto> CreateChatRoomAsync(int userId, CreateChatRoomDto createChatRoomDto)
        {
            var chatRoom = new ChatRoom
            {
                Name = createChatRoomDto.Name,
                Description = createChatRoomDto.Description,
                Type = createChatRoomDto.Type,
                CreatedBy = userId,
                CreatedAt = DateTime.UtcNow,
                UpdatedAt = DateTime.UtcNow,
                IsActive = true
            };

            var createdChatRoom = await _chatRoomRepository.CreateAsync(chatRoom);

            // 添加创建者为管理员
            await _chatRoomRepository.AddUserToChatRoomAsync(createdChatRoom.Id, userId, UserRole.Owner);

            // 添加其他成员
            if (createChatRoomDto.MemberIds != null && createChatRoomDto.MemberIds.Any())
            {
                foreach (var memberId in createChatRoomDto.MemberIds)
                {
                    if (memberId != userId) // 避免重复添加创建者
                    {
                        await _chatRoomRepository.AddUserToChatRoomAsync(createdChatRoom.Id, memberId, UserRole.Member);
                    }
                }
            }

            return await GetChatRoomAsync(createdChatRoom.Id, userId) ?? throw new InvalidOperationException("创建聊天室失败");
        }

        public async Task<ChatRoomDto?> GetChatRoomAsync(int chatRoomId, int userId)
        {
            // 检查用户是否是聊天室成员
            if (!await _chatRoomRepository.IsUserMemberAsync(chatRoomId, userId))
            {
                return null;
            }

            var chatRoom = await _chatRoomRepository.GetByIdAsync(chatRoomId);
            if (chatRoom == null) return null;

            var members = await _chatRoomRepository.GetChatRoomMembersAsync(chatRoomId);
            var lastMessage = await _messageRepository.GetLastMessageAsync(chatRoomId);
            var userChatRoom = await _chatRoomRepository.GetUserChatRoomAsync(chatRoomId, userId);

            var unreadCount = await _messageRepository.GetUnreadCountAsync(chatRoomId, userId, userChatRoom?.LastReadAt);

            return new ChatRoomDto
            {
                Id = chatRoom.Id,
                Name = chatRoom.Name,
                Description = chatRoom.Description,
                Type = chatRoom.Type,
                CreatedBy = chatRoom.CreatedBy,
                CreatedAt = chatRoom.CreatedAt,
                IsActive = chatRoom.IsActive,
                Members = members.Select(MapToUserDto).ToList(),
                LastMessage = lastMessage != null ? MapToMessageDto(lastMessage) : null,
                UnreadCount = unreadCount
            };
        }

        public async Task<List<ChatRoomDto>> GetUserChatRoomsAsync(int userId)
        {
            try
            {
                var chatRooms = await _chatRoomRepository.GetUserChatRoomsAsync(userId);
                var chatRoomDtos = new List<ChatRoomDto>();

                foreach (var chatRoom in chatRooms)
                {
                    try
                    {
                        var chatRoomDto = await GetChatRoomAsync(chatRoom.Id, userId);
                        if (chatRoomDto != null)
                        {
                            chatRoomDtos.Add(chatRoomDto);
                        }
                    }
                    catch (Exception ex)
                    {
                        // 记录错误但继续处理其他聊天室
                        Console.WriteLine($"获取聊天室 {chatRoom.Id} 信息时出错: {ex.Message}");
                    }
                }

                return chatRoomDtos.OrderByDescending(cr => cr.LastMessage?.CreatedAt ?? cr.CreatedAt).ToList();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取用户聊天室列表时出错: {ex.Message}");
                return new List<ChatRoomDto>();
            }
        }

        public async Task<ChatRoomDto?> GetOrCreateDirectChatAsync(int user1Id, int user2Id)
        {
            // 检查是否已存在直接聊天
            var existingChatRoom = await _chatRoomRepository.GetDirectChatRoomAsync(user1Id, user2Id);
            if (existingChatRoom != null)
            {
                return await GetChatRoomAsync(existingChatRoom.Id, user1Id);
            }

            // 获取用户信息以创建聊天室名称
            var user1 = await _userRepository.GetByIdAsync(user1Id);
            var user2 = await _userRepository.GetByIdAsync(user2Id);

            if (user1 == null || user2 == null)
            {
                throw new ArgumentException("用户不存在");
            }

            // 创建新的直接聊天室
            var createChatRoomDto = new CreateChatRoomDto
            {
                Name = $"{user1.DisplayName ?? user1.Username} & {user2.DisplayName ?? user2.Username}",
                Type = ChatRoomType.Direct,
                MemberIds = new List<int> { user2Id }
            };

            return await CreateChatRoomAsync(user1Id, createChatRoomDto);
        }

        public async Task<MessageDto> SendMessageAsync(int userId, SendMessageDto sendMessageDto)
        {
            // 检查用户是否是聊天室成员
            if (!await _chatRoomRepository.IsUserMemberAsync(sendMessageDto.ChatRoomId, userId))
            {
                throw new UnauthorizedAccessException("您不是此聊天室的成员");
            }

            var message = new Message
            {
                ChatRoomId = sendMessageDto.ChatRoomId,
                SenderId = userId,
                Content = sendMessageDto.Content,
                Type = sendMessageDto.Type,
                CreatedAt = DateTime.UtcNow
            };

            var createdMessage = await _messageRepository.CreateAsync(message);
            
            // 获取发送者信息
            var sender = await _userRepository.GetByIdAsync(userId);
            createdMessage.Sender = sender;

            return MapToMessageDto(createdMessage);
        }

        public async Task<ChatHistoryDto> GetChatHistoryAsync(int chatRoomId, int userId, int pageNumber = 1, int pageSize = 50)
        {
            // 检查用户是否是聊天室成员
            if (!await _chatRoomRepository.IsUserMemberAsync(chatRoomId, userId))
            {
                throw new UnauthorizedAccessException("您不是此聊天室的成员");
            }

            var messages = await _messageRepository.GetChatRoomMessagesAsync(chatRoomId, pageNumber, pageSize);
            var totalCount = await _messageRepository.GetTotalMessagesCountAsync(chatRoomId);
            var hasNextPage = (pageNumber * pageSize) < totalCount;

            return new ChatHistoryDto
            {
                Messages = messages.Select(MapToMessageDto).ToList(),
                TotalCount = totalCount,
                PageNumber = pageNumber,
                PageSize = pageSize,
                HasNextPage = hasNextPage
            };
        }

        public async Task<bool> JoinChatRoomAsync(int chatRoomId, int userId)
        {
            var chatRoom = await _chatRoomRepository.GetByIdAsync(chatRoomId);
            if (chatRoom == null || !chatRoom.IsActive)
            {
                return false;
            }

            // 检查用户是否已经是成员
            if (await _chatRoomRepository.IsUserMemberAsync(chatRoomId, userId))
            {
                return true; // 已经是成员
            }

            await _chatRoomRepository.AddUserToChatRoomAsync(chatRoomId, userId, UserRole.Member);
            return true;
        }

        public async Task<bool> LeaveChatRoomAsync(int chatRoomId, int userId)
        {
            if (!await _chatRoomRepository.IsUserMemberAsync(chatRoomId, userId))
            {
                return false;
            }

            await _chatRoomRepository.RemoveUserFromChatRoomAsync(chatRoomId, userId);
            return true;
        }

        public async Task<bool> MarkAsReadAsync(int chatRoomId, int userId)
        {
            if (!await _chatRoomRepository.IsUserMemberAsync(chatRoomId, userId))
            {
                return false;
            }

            await _chatRoomRepository.UpdateLastReadAsync(chatRoomId, userId, DateTime.UtcNow);

            return true;
        }

        public async Task<List<UserDto>> GetChatRoomMembersAsync(int chatRoomId, int userId)
        {
            // 检查用户是否是聊天室成员
            if (!await _chatRoomRepository.IsUserMemberAsync(chatRoomId, userId))
            {
                throw new UnauthorizedAccessException("您不是此聊天室的成员");
            }

            var members = await _chatRoomRepository.GetChatRoomMembersAsync(chatRoomId);
            return members.Select(MapToUserDto).ToList();
        }

        public async Task<bool> DeleteMessageAsync(int messageId, int userId)
        {
            var message = await _messageRepository.GetByIdAsync(messageId);
            if (message == null || message.SenderId != userId)
            {
                return false;
            }

            return await _messageRepository.SoftDeleteAsync(messageId);
        }

        public async Task<MessageDto?> EditMessageAsync(int messageId, int userId, string newContent)
        {
            var message = await _messageRepository.GetByIdAsync(messageId);
            if (message == null || message.SenderId != userId)
            {
                return null;
            }

            message.Content = newContent;
            var updatedMessage = await _messageRepository.UpdateAsync(message);
            return MapToMessageDto(updatedMessage);
        }

        private static UserDto MapToUserDto(User user)
        {
            return new UserDto
            {
                Id = user.Id,
                Username = user.Username,
                Email = user.Email,
                DisplayName = user.DisplayName,
                Avatar = user.Avatar,
                IsOnline = user.IsOnline,
                LastSeenAt = user.LastSeenAt,
                CreatedAt = user.CreatedAt
            };
        }

        private static MessageDto MapToMessageDto(Message message)
        {
            return new MessageDto
            {
                Id = message.Id,
                ChatRoomId = message.ChatRoomId,
                SenderId = message.SenderId,
                Content = message.Content,
                Type = message.Type,
                CreatedAt = message.CreatedAt,
                IsEdited = message.IsEdited,
                EditedAt = message.EditedAt,
                Sender = message.Sender != null ? new UserDto
                {
                    Id = message.Sender.Id,
                    Username = message.Sender.Username,
                    Email = message.Sender.Email,
                    DisplayName = message.Sender.DisplayName,
                    Avatar = message.Sender.Avatar,
                    IsOnline = message.Sender.IsOnline,
                    LastSeenAt = message.Sender.LastSeenAt,
                    CreatedAt = message.Sender.CreatedAt
                } : null
            };
        }
    }
}
